package net.yxsoft.chainmaker;

import com.alibaba.fastjson.JSONObject;
import org.chainmaker.pb.common.ContractOuterClass;
import org.chainmaker.pb.common.Request;
import org.chainmaker.pb.common.ResultOuterClass;
import org.chainmaker.pb.config.ChainConfigOuterClass;
import org.chainmaker.sdk.ChainClient;
import org.chainmaker.sdk.User;
import org.chainmaker.sdk.utils.FileUtils;
import org.chainmaker.sdk.utils.SdkUtils;

import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.util.HashMap;
import java.util.Map;


public class Contract {

    private static final String QUERY_CONTRACT_METHOD = "query";
    private static final String INVOKE_CONTRACT_METHOD = "increase";
    private static final String CONTRACT_NAME = "counter_sdk_java_demo";
    private static final String CONTRACT_NAME2 = "sharedata403";
    private static final String CONTRACT_NAME3 = "evidence405";
    private static final String CONTRACT_FILE_PATH = "src/main/resources/rust-fact-1.0.0.wasm";

    public static void createContract(ChainClient chainClient, User user) {
        ResultOuterClass.TxResponse responseInfo = null;
        try {
            byte[] byteCode = FileUtils.getResourceFileBytes(CONTRACT_FILE_PATH);

            // 1. create payload
            Request.Payload payload = chainClient.createContractCreatePayload(CONTRACT_NAME, "1", byteCode,
                    ContractOuterClass.RuntimeType.WASMER, null);
            //2. create payloads with endorsement
            Request.EndorsementEntry[] endorsementEntries = SdkUtils
                    .getEndorsers(payload, new User[]{user});

            // 3. send request
            responseInfo = chainClient.sendContractManageRequest(payload, endorsementEntries, 10000, 10000);
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("创建合约结果：");
        System.out.println(responseInfo);
    }

    public static void authorize(ChainClient chainClient, String category) throws NoSuchAlgorithmException, InvalidKeySpecException {

        Map<String, byte[]> paramMap = new HashMap<>();
//        String fromAddress = chainmaker.sdk.demo.CryptoUtils.certToAddrStr(InitClient.chainClient.getClientUser().getCertificate(), ChainConfigOuterClass.AddrType.CHAINMAKER);
        String fromAddress = CryptoUtils.certToAddrStr(InitClient.chainClient.getClientUser().getCertificate(), ChainConfigOuterClass.AddrType.ETHEREUM);
        JSONObject jsonObject = new JSONObject();
//        jsonObject.put("account", fromAddress);
//        jsonObject.put("account", "c7fa296eeb508b71c740679f46f8a3882db22d04");
        jsonObject.put("account", fromAddress);
        jsonObject.put("category", category);
        System.out.println(jsonObject.toString());

        paramMap.put("data", jsonObject.toString().getBytes());

        ResultOuterClass.TxResponse responseInfo = null;
        try {
            responseInfo = chainClient.invokeContract(CONTRACT_NAME2, "authorize",
                    null, paramMap, 10000, 10000);
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("authorize 执行合约结果：");
        System.out.println(responseInfo);

    }

    public static void getauthorize(ChainClient chainClient) throws NoSuchAlgorithmException, InvalidKeySpecException {
        Map<String, byte[]> paramMap = new HashMap<>();
        String fromAddress = CryptoUtils.certToAddrStr(InitClient.chainClient.getClientUser().getCertificate(), ChainConfigOuterClass.AddrType.CHAINMAKER);

        JSONObject jsonObject = new JSONObject();
        jsonObject.put("account", fromAddress);
        jsonObject.put("category", "0");
        System.out.println(jsonObject.toString());

        paramMap.put("data", jsonObject.toString().getBytes());

        ResultOuterClass.TxResponse responseInfo = null;
        try {
            responseInfo = chainClient.invokeContract(CONTRACT_NAME2, "getauthorize",
                    null, paramMap, 10000, 10000);
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("getauthorize 查询合约结果：");
        System.out.println(responseInfo);
    }

    public static void getsender(ChainClient chainClient) throws NoSuchAlgorithmException, InvalidKeySpecException {

        ResultOuterClass.TxResponse responseInfo = null;
        try {
            responseInfo = chainClient.invokeContract(CONTRACT_NAME2, "getsender",
                    null, null, 10000, 10000);
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("getsender 查询合约结果：");
        System.out.println(responseInfo);

    }

    public static void setOrderData(ChainClient chainClient, int i) throws NoSuchAlgorithmException, InvalidKeySpecException {

        Map<String, byte[]> paramMap = new HashMap<>();
        for (int j = 0; j < i; j++) {
            JSONObject baseitem = new JSONObject();
            baseitem.put("Name", "name111");
            baseitem.put("Hash", "hash222");
            baseitem.put("CreateTM", 11223344);
            baseitem.put("Remark", "Remark111");
            baseitem.put("TxHash", "TxHash111");

            JSONObject setItem = new JSONObject();
            setItem.put("DataInfo", baseitem);
            setItem.put("OrderId", "orderId" + j);

            paramMap.put("data", setItem.toString().getBytes());

            System.out.println("data-->" + setItem.toString());

            ResultOuterClass.TxResponse responseInfo = null;
            try {
                responseInfo = chainClient.invokeContract(CONTRACT_NAME2, "setOrderData",
                        null, paramMap, 10000, 10000);
            } catch (Exception e) {
                e.printStackTrace();
            }
            System.out.println("setOrderData 执行合约结果：");
            System.out.println(responseInfo);
        }
    }

    public static void setStateData(ChainClient chainClient, int i) throws NoSuchAlgorithmException, InvalidKeySpecException {

        Map<String, byte[]> paramMap = new HashMap<>();
        for (int j = 0; j < i; j++) {
            JSONObject baseitem = new JSONObject();
            baseitem.put("Name", "name111");
            baseitem.put("Hash", "hash222");
            baseitem.put("CreateTM", 11223344);
            baseitem.put("Remark", "Remark111");
            baseitem.put("TxHash", "TxHash111");

            JSONObject setItem = new JSONObject();
            setItem.put("DataInfo", baseitem);
            setItem.put("OrderId", "stateId" + j);

            paramMap.put("data", setItem.toString().getBytes());

            System.out.println("data-->" + setItem.toString());

            ResultOuterClass.TxResponse responseInfo = null;
            try {
                responseInfo = chainClient.invokeContract(CONTRACT_NAME2, "setStateData",
                        null, paramMap, 10000, 10000);
            } catch (Exception e) {
                e.printStackTrace();
            }
            System.out.println("setStateData 执行合约结果：");
            System.out.println(responseInfo);
        }
    }

    public static void getOrderData(ChainClient chainClient, String orderId) throws NoSuchAlgorithmException, InvalidKeySpecException {

        Map<String, byte[]> paramMap = new HashMap<>();
        paramMap.put("orderId", orderId.getBytes());

        ResultOuterClass.TxResponse responseInfo = null;
        try {
            responseInfo = chainClient.invokeContract(CONTRACT_NAME2, "getOrderData",
                    null, paramMap, 10000, 10000);
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("getOrderData 执行合约结果：");
        System.out.println(responseInfo);

    }

    public static void getStateData(ChainClient chainClient, String stateId) throws NoSuchAlgorithmException, InvalidKeySpecException {

        Map<String, byte[]> paramMap = new HashMap<>();
        paramMap.put("stateId", stateId.getBytes());

        ResultOuterClass.TxResponse responseInfo = null;
        try {
            responseInfo = chainClient.invokeContract(CONTRACT_NAME2, "getStateData",
                    null, paramMap, 10000, 10000);
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("getStateData 执行合约结果：");
        System.out.println(responseInfo);

    }

    public static void getOrders(ChainClient chainClient, int pagesize, int pagenum) throws NoSuchAlgorithmException, InvalidKeySpecException {

        Map<String, byte[]> paramMap = new HashMap<>();

        JSONObject page = new JSONObject();
        page.put("PageSize", pagesize);
        page.put("PageNum", pagenum);
        page.put("Key", 0);

        paramMap.put("data", page.toString().getBytes());

        ResultOuterClass.TxResponse responseInfo = null;
        try {
            responseInfo = chainClient.invokeContract(CONTRACT_NAME2, "getOrders",
                    null, paramMap, 10000, 10000);
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("getOrders 执行合约结果：");
        System.out.println(responseInfo);

    }

    public static void getStates(ChainClient chainClient, int pagesize, int pagenum) throws NoSuchAlgorithmException, InvalidKeySpecException {

        Map<String, byte[]> paramMap = new HashMap<>();

        JSONObject page = new JSONObject();
        page.put("PageSize", pagesize);
        page.put("PageNum", pagenum);
        page.put("Key", 0);

        paramMap.put("data", page.toString().getBytes());

        ResultOuterClass.TxResponse responseInfo = null;
        try {
            responseInfo = chainClient.invokeContract(CONTRACT_NAME2, "getStates",
                    null, paramMap, 10000, 10000);
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("getOrders 执行合约结果：");
        System.out.println(responseInfo);

    }

    public static void checkOrderExist(ChainClient chainClient, String orderId) throws NoSuchAlgorithmException, InvalidKeySpecException {

        Map<String, byte[]> paramMap = new HashMap<>();
        paramMap.put("orderId", orderId.getBytes());

        ResultOuterClass.TxResponse responseInfo = null;
        try {
            responseInfo = chainClient.invokeContract(CONTRACT_NAME2, "checkOrderExist",
                    null, paramMap, 10000, 10000);
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("checkOrderExist 执行合约结果：");
        System.out.println(responseInfo);

    }

    public static void checkStateExist(ChainClient chainClient, String stateId) throws NoSuchAlgorithmException, InvalidKeySpecException {

        Map<String, byte[]> paramMap = new HashMap<>();
        paramMap.put("stateId", stateId.getBytes());

        ResultOuterClass.TxResponse responseInfo = null;
        try {
            responseInfo = chainClient.invokeContract(CONTRACT_NAME2, "checkStateExist",
                    null, paramMap, 10000, 10000);
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("checkStateExist 执行合约结果：");
        System.out.println(responseInfo);

    }

    public static void getOrderSize(ChainClient chainClient) {

        ResultOuterClass.TxResponse responseInfo = null;
        try {
            responseInfo = chainClient.invokeContract(CONTRACT_NAME2, "getOrderSize",
                    null, null, 10000, 10000);
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("getOrderSize 查询合约结果：");
        System.out.println(responseInfo);

    }

    public static void getStateSize(ChainClient chainClient) {

        ResultOuterClass.TxResponse responseInfo = null;
        try {
            responseInfo = chainClient.invokeContract(CONTRACT_NAME2, "getStateSize",
                    null, null, 10000, 10000);
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("getStateSize 查询合约结果：");
        System.out.println(responseInfo);

    }

    public static void getevidenceowner(ChainClient chainClient) {

        ResultOuterClass.TxResponse responseInfo = null;
        try {
            responseInfo = chainClient.invokeContract(CONTRACT_NAME3, "getOwner",
                    null, null, 10000, 10000);
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("getevidenceowner 查询合约结果：");
        System.out.println(responseInfo);

    }

    public static void getevidencesender(ChainClient chainClient) throws NoSuchAlgorithmException, InvalidKeySpecException {

        ResultOuterClass.TxResponse responseInfo = null;
        try {
            responseInfo = chainClient.invokeContract(CONTRACT_NAME3, "getSender",
                    null, null, 10000, 10000);
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("getevidencesender 查询合约结果：");
        System.out.println(responseInfo);

    }

    public static void setEvidence(ChainClient chainClient, int i) throws NoSuchAlgorithmException, InvalidKeySpecException {

        Map<String, byte[]> paramMap = new HashMap<>();
        for (int j = 0; j < i; j++) {
            JSONObject evidenceData = new JSONObject();
            evidenceData.put("EvdcHash", "evdcHash" + j);
            evidenceData.put("Name", "name111");
            evidenceData.put("CreateTM", 11223344);
            evidenceData.put("EvidenceType", "1");
            evidenceData.put("Remark", "Remark111");
            evidenceData.put("TxHash", "TxHash111");

            JSONObject setItem = new JSONObject();
            setItem.put("DataInfo", evidenceData);
            setItem.put("EvdcHash", "evdcHash" + j);

            paramMap.put("data", setItem.toString().getBytes());

            System.out.println("data-->" + setItem.toString());

            ResultOuterClass.TxResponse responseInfo = null;
            try {
                responseInfo = chainClient.invokeContract(CONTRACT_NAME3, "setEvidence",
                        null, paramMap, 10000, 10000);
            } catch (Exception e) {
                e.printStackTrace();
            }
            System.out.println("setEvidence 执行合约结果：");
            System.out.println(responseInfo);
        }
    }

    public static void getEvidence(ChainClient chainClient, String evdcHash) throws NoSuchAlgorithmException, InvalidKeySpecException {

        Map<String, byte[]> paramMap = new HashMap<>();
        paramMap.put("evdcHash", evdcHash.getBytes());

        ResultOuterClass.TxResponse responseInfo = null;
        try {
            responseInfo = chainClient.invokeContract(CONTRACT_NAME3, "getEvidence",
                    null, paramMap, 10000, 10000);
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("getEvidence 执行合约结果：");
        System.out.println(responseInfo);

    }

    public static void checkEvidenceExist(ChainClient chainClient, String evdcHash) {

        Map<String, byte[]> paramMap = new HashMap<>();
        paramMap.put("evdcHash", evdcHash.getBytes());

        ResultOuterClass.TxResponse responseInfo = null;
        try {
            responseInfo = chainClient.invokeContract(CONTRACT_NAME3, "checkEvidenceExist",
                    null, paramMap, 10000, 10000);
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("checkEvidenceExist 执行合约结果：");
        System.out.println(responseInfo);

    }

    public static void getEvidenceSize(ChainClient chainClient) {

        ResultOuterClass.TxResponse responseInfo = null;
        try {
            responseInfo = chainClient.invokeContract(CONTRACT_NAME3, "getEvidenceSize",
                    null, null, 10000, 10000);
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("getEvidenceSize 查询合约结果：");
        System.out.println(responseInfo);

    }

    public static void getEvidences(ChainClient chainClient, int pagesize, int pagenum) throws NoSuchAlgorithmException, InvalidKeySpecException {

        Map<String, byte[]> paramMap = new HashMap<>();

        JSONObject page = new JSONObject();
        page.put("PageSize", pagesize);
        page.put("PageNum", pagenum);

        paramMap.put("data", page.toString().getBytes());

        ResultOuterClass.TxResponse responseInfo = null;
        try {
            responseInfo = chainClient.invokeContract(CONTRACT_NAME3, "getEvidences",
                    null, paramMap, 10000, 10000);
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("getEvidences 执行合约结果：");
        System.out.println(responseInfo);

    }

    public static void invokeContract(ChainClient chainClient) {
        ResultOuterClass.TxResponse responseInfo = null;
        try {
            responseInfo = chainClient.invokeContract(CONTRACT_NAME, INVOKE_CONTRACT_METHOD,
                    null, null, 10000, 10000);
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("执行合约结果：");
        System.out.println(responseInfo);
    }

    public static void queryContract(ChainClient chainClient) {
        ResultOuterClass.TxResponse responseInfo = null;
        try {
            responseInfo = chainClient.queryContract(CONTRACT_NAME, QUERY_CONTRACT_METHOD,
                    null, null, 10000);
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("查询合约结果：");
        System.out.println(responseInfo);
    }
}
